﻿using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Common
{
    /// <summary>
    /// 方法返回实体
    /// </summary>
    /// <remarks>
    /// <![CDATA[
    /// 此对象通常用于当一个方法需要返回多种数据时使用
    /// ]]>
    /// </remarks>
    [DebuggerDisplay("Code={Code},Message={Message}")]
    public class FuncResult
    {
        /// <summary>
        /// 失败的编码
        /// </summary>
        public const string _FAIL_CODE = "0500";
        /// <summary>
        /// 成功的编码
        /// </summary>
        public const string _SUCCESS_CODE = "0000";
        /// <summary>
        /// 成功的默认信息
        /// </summary>
        public const string _SUCCESS_MESSAGE = "操作成功";
        #region Property

        /// <summary>
        /// 状态码
        /// </summary>
        public string Code { get; set; }

        /// <summary>
        /// 错误信息
        /// </summary>
        public string Message { get; set; }

        #endregion

        #region SuccessResult

        /// <summary>
        /// [<![CDATA[返回一个成功的，带有数据的FuncResult<T>对象]]>
        /// </summary>
        /// <typeparam name="T">返回内容的类型</typeparam>
        /// <param name="content">返回内容</param>
        /// <param name="message">返回信息</param>
        /// <example>
        /// <code>
        /// <![CDATA[
        ///        private void FailResultDemo()
        ///        {
        ///             //数据
        ///             List<string> list=new List<string>();
        ///             list.Add("Data");
        ///             
        ///             //或者构造一个有无状态码的成功对象
        ///             var result=FuncResult.FailResult(list);
        ///        }
        /// ]]>
        /// </code>
        /// </example>
        /// <returns>[<![CDATA[返回一个成功的，带有数据的FuncResult<T>对象]]></returns>
        public static FuncResult<T> Success<T>(T content, string message = null)
        {
            FuncResult<T> result = new FuncResult<T>()
            {
                Data = content,
                Code = _SUCCESS_CODE,
                Message = message ?? _SUCCESS_MESSAGE
            };
            return result;
        }

        /// <summary>
        /// 返回一个成功的FuncResult对象
        /// </summary>
        /// <example>
        /// <code>
        ///        private void FailResultDemo()
        ///        {
        ///             //或者构造一个有无状态码的成功对象
        ///            var result = FuncResult.FailResult();
        ///        }
        /// </code>
        /// </example>
        /// <returns>返回一个成功的FuncResult对象</returns>
        public static FuncResult Success(string message = null)
        {
            FuncResult result = new FuncResult()
            {
                Code = _SUCCESS_CODE,
                Message = message ?? _SUCCESS_MESSAGE
            };
            return result;
        }
        #endregion

        #region FailResult

        /// <summary>
        /// 返回失败
        /// </summary>
        /// <typeparam name="T">返回内容的类型</typeparam>
        /// <param name="data">返回内容</param>
        /// <param name="message">错误信息</param>
        /// <param name="code">返回码</param>
        /// <example>
        /// <code>
        /// <![CDATA[
        ///        private void FailResultDemo()
        ///        {
        ///             //数据
        ///             List<string> list=new List<string>();
        ///             list.Add("Data");
        ///             
        ///             //构造一个有状态码的失败对象
        ///             var result=FuncResult.FailResult(list,"失败信息",1);//注意：1是状态;
        ///             
        ///             //或者构造一个有无状态码的失败对象
        ///             result=FuncResult.FailResult(list,"失败信息");
        ///        }
        /// ]]>
        /// </code>
        /// </example>
        /// <returns>[<![CDATA[返回一个失败的FuncResult<T>对象]]></returns>
        public static FuncResult<T> Fail<T>(T data, string message, string code = _FAIL_CODE)
        {
            FuncResult<T> result = new FuncResult<T>()
            {
                Data = data,
                Message = message,
                Code = code,
            };
            return result;
        }

        /// <summary>
        /// 返回失败
        /// </summary>
        /// <typeparam name="T">返回内容的类型</typeparam>
        /// <param name="message">错误信息</param>
        /// <param name="code">返回码</param>
        /// <example>
        /// <code>
        /// <![CDATA[
        ///  private void FailResultDemo()
        ///  {
        ///       //构造一个有状态码的失败对象[<![CDATA[
        ///       var result=FuncResult.FailResult<string>("失败信息",1);//注意：1是状态;      
        ///             
        ///       //或者构造一个有无状态码的失败对象      
        ///       result=FuncResult.FailResult<string>("失败信息");      
        ///  }      
        ///  ]]>     
        /// </code>
        /// </example>
        /// <returns>[<![CDATA[返回一个失败的FuncResult<T>对象]]></returns>
        public static FuncResult<T> Fail<T>(string message, string code = _FAIL_CODE)
        {
            T defaultValue = default(T);
            return Fail(defaultValue, message, code);
        }

        /// <summary>
        /// 返回失败
        /// </summary>
        /// <param name="message">错误信息</param>
        /// <param name="code">返回码</param>
        /// <example>
        /// <code>
        ///        private void FailResultDemo()
        ///        {
        ///             //构造一个有状态码的失败对象
        ///             var result=FuncResult.FailResult("失败信息",1);//注意：1是状态;
        ///             
        ///             //或者构造一个有无状态码的失败对象
        ///             result=FuncResult.FailResult("失败信息");
        ///        }
        /// </code>
        /// </example>
        /// <returns>返回一个失败的FuncResult对象</returns>
        public static FuncResult Fail(string message, string code = _FAIL_CODE)
        {
            FuncResult result = new FuncResult()
            {
                Message = message,
                Code = code,
            };
            return result;
        }
        #endregion

        /// <summary>
        /// <![CDATA[返回result的Success]]>
        /// </summary>
        /// <param name="result"></param>
        public static implicit operator bool(FuncResult result)
        {
            return result != null && result.Code == _SUCCESS_CODE;
        }
        /// <summary>
        /// 分页成功返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="array"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public static FuncResultPagination<T> Success<T>(IEnumerable<T> array, int total)
        {
            return new FuncResultPagination<T>
            {
                Code = _SUCCESS_CODE,
                Message = _SUCCESS_MESSAGE,
                Data = new PaginationResult<T>
                {
                    Total = total,
                    Array = array ?? new List<T>()
                }
            };
        }
        /// <summary>
        /// 分页失败返回
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="message"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static FuncResultPagination<T> FailList<T>(string message, string code = _FAIL_CODE)
        {
            return new FuncResultPagination<T>
            {
                Code = code,
                Message = message
            };
        }
    }

    /// <summary>
    /// 方法返回值
    /// </summary>
    /// <typeparam name="T">返回内容数据类型</typeparam>
    [DebuggerDisplay("Code={Code},Message={Message},Data={Data}")]
    public class FuncResult<T> : FuncResult
    {
        /// <summary>
        /// 返回的内容
        /// </summary>
        public T Data { get; set; }

        /// <summary>
        /// <![CDATA[T data 隐式转换 FuncResult<T>.SuccessResult(data)]]>
        /// </summary>
        /// <param name="data"></param>
        public static implicit operator FuncResult<T>(T data)
        {
            return FuncResult.Success(data);
        }
    }
    /// <summary>
    /// 分页返回
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class FuncResultPagination<T> : FuncResult<PaginationResult<T>>
    {

    }
}
